/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package l1j.server.server.model.item.executor;

import static l1j.server.server.model.skill.L1SkillId.*;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import l1j.server.server.datatables.ItemTable;
import l1j.server.server.model.skill.L1BuffUtil;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.packets.server.S_ServerMessage;
import l1j.server.server.packets.server.S_SkillBrave;
import l1j.server.server.packets.server.S_SkillSound;
import l1j.server.server.utils.PerformanceTimer;

@XmlAccessorType(XmlAccessType.FIELD)
public class L1BravePotion {

	private static Logger _log = Logger.getLogger(L1BravePotion.class.getName());
	
	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name = "ItemEffectList")
	private static class ItemEffectList implements Iterable<L1BravePotion> {
		@XmlElement(name = "Item")
		private List<L1BravePotion> _list;

		public Iterator<L1BravePotion> iterator() {
			return _list.iterator();
		}
	}

	@XmlAccessorType(XmlAccessType.FIELD)
	private static class Effect {
		@XmlAttribute(name = "Time")
		private int _time;
		
		private int getTime() {
			return _time;
		}
		
		@XmlAttribute(name = "GfxId")
		private int _gfxid;
		
		private int getGfxId() {
			return _gfxid;
		}
		
		@XmlAttribute(name = "GfxId2")
		private int _gfxid2;
		
		private int getGfxId2() {
			return _gfxid2;
		}
	}

	private static final String PATH = "./data/xml/Item/BravePotion.xml";

	private static final HashMap<Integer, L1BravePotion> _dataMap = new HashMap<Integer, L1BravePotion>();

	public static L1BravePotion get(int id) {
		return _dataMap.get(id);
	}

	@XmlAttribute(name = "ItemId")
	private int _itemId;

	private int getItemId() {
		return _itemId;
	}

	@XmlAttribute(name = "ClassInitial")
	private String _classInitial;

	private String getClassInitial() {
		return _classInitial;
	}

	@XmlElement(name = "Effect")
	private Effect _effect;
	
	private Effect getEffect() {
		return _effect;
	}

	public static void load() {
		PerformanceTimer timer = new PerformanceTimer();
		System.out.print("loading brave potion...");
		try {
			JAXBContext context = JAXBContext.newInstance(L1BravePotion.ItemEffectList.class);

			Unmarshaller um = context.createUnmarshaller();

			File file = new File(PATH);
			ItemEffectList list = (ItemEffectList) um.unmarshal(file);

			for (L1BravePotion each : list) {
				if (ItemTable.getInstance().getTemplate(each.getItemId()) == null) {
					System.out.println("アイテムID " + each.getItemId() + " のテンプレートが見つかりません。");
				} else {
					_dataMap.put(each.getItemId(), each);
				}
			}
		} catch (Exception e) {
			_log.log(Level.SEVERE, PATH + "のロードに失敗。", e);
			System.exit(0);
		}
		System.out.println("OK! " + timer.elapsedTimeMillis() + "ms");
	}

	public boolean use(L1PcInstance pc) {
		if (pc.hasSkillEffect(71) == true) { // ディケイ ポーションの状態
			pc.sendPackets(new S_ServerMessage(698)); // 魔力によって何も飲むことができません。
			return false;
		}

		// 使用可能クラスの判定
		if (getClassInitial().equalsIgnoreCase("P") && !pc.isCrown()) {
			pc.sendPackets(new S_ServerMessage(264));
			// \f1あなたのクラスではこのアイテムは使用できません。
			return false;
		} else if (getClassInitial().equalsIgnoreCase("K") && !pc.isKnight()) {
			pc.sendPackets(new S_ServerMessage(264));
			// \f1あなたのクラスではこのアイテムは使用できません。
			return false;
		} else if (getClassInitial().equalsIgnoreCase("E") && !pc.isElf()) {
			pc.sendPackets(new S_ServerMessage(264));
			// \f1あなたのクラスではこのアイテムは使用できません。
			return false;
		} else if (getClassInitial().equalsIgnoreCase("W") && !pc.isWizard()) {
			pc.sendPackets(new S_ServerMessage(264));
			// \f1あなたのクラスではこのアイテムは使用できません。
			return false;
		} else if (getClassInitial().equalsIgnoreCase("D") && !pc.isDarkelf()) {
			pc.sendPackets(new S_ServerMessage(264));
			// \f1あなたのクラスではこのアイテムは使用できません。
			return false;
		} else if (getClassInitial().equalsIgnoreCase("R") && !pc.isDragonKnight()) {
			pc.sendPackets(new S_ServerMessage(264));
			// \f1あなたのクラスではこのアイテムは使用できません。
			return false;
		} else if (getClassInitial().equalsIgnoreCase("I") && !pc.isIllusionist()) {
			pc.sendPackets(new S_ServerMessage(264));
			// \f1あなたのクラスではこのアイテムは使用できません。
			return false;
		}
		
		// アブソルート バリアの解除
		L1BuffUtil.cancelBarrier(pc);

		if (getItemId() == 49158) { // ユグドラの実
			if (pc.hasSkillEffect(STATUS_BRAVE)) { // 名誉のコインとは重複しない
				pc.killSkillEffectTimer(STATUS_BRAVE);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
		} else if (getItemId() == 40068) { // エルヴン ワッフル
			if (pc.hasSkillEffect(STATUS_BRAVE)) { // 名誉のコインとは重複しない
				pc.killSkillEffectTimer(STATUS_BRAVE);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
			if (pc.hasSkillEffect(WIND_WALK)) { // ウィンドウォークとは重複しない
				pc.killSkillEffectTimer(WIND_WALK);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
		} else if (getItemId() == 140068) { // 祝福されたエルヴン ワッフル
			if (pc.hasSkillEffect(STATUS_BRAVE)) { // 名誉のコインとは重複しない
				pc.killSkillEffectTimer(STATUS_BRAVE);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
			if (pc.hasSkillEffect(WIND_WALK)) { // ウィンドウォークとは重複しない
				pc.killSkillEffectTimer(WIND_WALK);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
		} else if (getItemId() == 40733) { // 名誉のコイン
			if (pc.hasSkillEffect(STATUS_ELFBRAVE)) { // エルヴンワッフルとは重複しない
				pc.killSkillEffectTimer(STATUS_ELFBRAVE);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
			if (pc.hasSkillEffect(HOLY_WALK)) { // ホーリーウォークとは重複しない
				pc.killSkillEffectTimer(HOLY_WALK);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
			if (pc.hasSkillEffect(MOVING_ACCELERATION)) { // ムービングアクセレーションとは重複しない
				pc.killSkillEffectTimer(MOVING_ACCELERATION);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
			if (pc.hasSkillEffect(WIND_WALK)) { // ウィンドウォークとは重複しない
				pc.killSkillEffectTimer(WIND_WALK);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
			if (pc.hasSkillEffect(STATUS_RIBRAVE)) { // ユグドラの実とは重複しない
				pc.killSkillEffectTimer(STATUS_RIBRAVE);
				// XXX ユグドラの実のアイコンを消す方法が不明
				pc.setBraveSpeed(0);
			}
			if (pc.hasSkillEffect(BLOODLUST)) { // ブラッドラストとは重複しない
				pc.killSkillEffectTimer(BLOODLUST);
				pc.sendPackets(new S_SkillBrave(pc.getId(), 0, 0));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 0, 0));
				pc.setBraveSpeed(0);
			}
		}

		Effect effect = getEffect();
		if (effect.getGfxId2() == 0) { // ユグドラの実
			pc.sendPackets(new S_SkillSound(pc.getId(), effect.getGfxId()));
			pc.broadcastPacket(new S_SkillSound(pc.getId(), effect.getGfxId()));
			pc.setSkillEffect(STATUS_RIBRAVE, effect.getTime() * 1000);
		} else {
			pc.sendPackets(new S_SkillBrave(pc.getId(), effect.getGfxId2(), effect.getTime()));
			pc.broadcastPacket(new S_SkillBrave(pc.getId(), effect.getGfxId2(), 0));
			pc.sendPackets(new S_SkillSound(pc.getId(), effect.getGfxId()));
			pc.broadcastPacket(new S_SkillSound(pc.getId(), effect.getGfxId()));
			pc.setSkillEffect(STATUS_BRAVE, effect.getTime() * 1000);
		}
		pc.setBraveSpeed(1);
		
		return true;
	}

}
